package trans.anno;
import java.io.*;

import util.gen.*;
import java.util.*;

/**Takes several tab delimited region files (chrom, start, stop, ...), creates the union and writes to disk.
 * Assumes the first base is zero, and the stop/end of a region is inclusive thus length = end-start+1 .
 * 
 * Enter a name of a directory containing the files.*/
public class MergeRegions {
	
	public static void main(String[] args) {
		if (args.length ==0) Misc.printExit("\nEnter a full path directory name containing region files to merge (tab delimited: chrom, start, end, ...). Note, " +
				"zero coordinates supported and the end coordinate is included, ie no interbase numbering.\n");
		File directory = new File(args[0]);
		File[] regionFiles = IO.extractFiles(directory);
		
		//load and sort regions
		Region[][] regions = new Region[regionFiles.length][];
		RegionComparator comp = new RegionComparator();
		for (int i=0; i<regionFiles.length; i++) {
			regions[i] = Region.parseRegions(regionFiles[i]);
			Arrays.sort(regions[i], comp);
		}
		
		//find all chromosomes and the maxBase
		TreeMap map = new TreeMap();
		for (int i=0; i<regions.length; i++){
			for (int j=0; j< regions[i].length; j++){
				//does chromosome exist
				Object obj = map.get(regions[i][j].getChromosome());
				if (obj == null){
					map.put(regions[i][j].getChromosome(), new Integer(regions[i][j].getEnd()));
				}
				//exists, reset maxBase?
				else {
					int num = ((Integer)obj).intValue();
					if (regions[i][j].getEnd() > num) map.put(regions[i][j].getChromosome(), new Integer(regions[i][j].getEnd()));
				}
			}
		}
		
		//for each chromosome make merge
		Iterator it = map.keySet().iterator();
		File mergedFile;
		if (directory.isDirectory() == false){
			mergedFile = new File(directory+".merged");
		}
		else mergedFile = new File(directory,"mergedUnion.txt");
		try {
			PrintWriter out = new PrintWriter( new FileWriter( mergedFile));
			while (it.hasNext()){
				//get name of chromosome and maxBase
				String chrom = (String)it.next();
				int maxBase =((Integer)map.get(chrom)).intValue();
				//make boolean array to hold whether it's flagged, initially they are all false
				boolean[] bps = new boolean[maxBase+1];
				//for each Region[] scan and throw booleans to true
				for (int i=0; i<regions.length; i++){
					boolean found = false;
					for (int j=0; j< regions[i].length; j++){
						//correct chromosome?
						if (regions[i][j].getChromosome().equals(chrom)){
							int stop = regions[i][j].getEnd()+1;
							for (int k=regions[i][j].getStart(); k< stop; k++){
								bps[k] = true;
							}
							found = true;
						}
						else if (found) break;
					}
				}
				//print merged chrom
				print(chrom, bps, out);
			}
			out.close();
		} catch (IOException e){
			e.printStackTrace();
		}
		
		
	}
	public static void print(String chromosome, boolean[] bps, PrintWriter out){
		boolean in = false;
		int i=0;
		for (; i<bps.length; i++){
			//start new line?
			if (bps[i] && in==false){
				out.print(chromosome+"\t"+i+"\t");
				in = true;
			}
			//close old?
			else if (in && bps[i] == false){
				out.println(i-1);
				in = false;
			}
		}
		//close old?
		if (in){
			if (bps[i-1]) out.println(i-1);
			else out.println(i-2);
		}
	}
	
}
